package com.kkb.kkbadmin.service.impl;

import com.kkb.kkbadmin.service.FameService;
import com.kkb.kkbcommon.exception.Asserts;
import com.kkb.kkbcommon.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.Set;


/**
 * @ClassName FameServiceImpl
 * @Description TODO
 * @Author moses
 * @Date 2021/8/14
 **/
@Service
public class FameServiceImpl implements FameService {

    /**
     * redis数据结构的key
     */
    private static final String STUDENT_KEY = "student";
    private static final String TUTOR_KEY = "tutor";
    
    @Autowired
    private RedisService redisService;

    /**
     * 添加学生的Id到redis排行榜
     *
     * @param id   学生的id
     * @param rank 学生的排名
     */
    @Override
    public void addStudentIdWithRedis(Long id, Double rank) {

        //判断是否超出排名范围
        Long count = redisService.zCount(STUDENT_KEY);
        if (rank > count + 1 || rank < 1) {
            Asserts.fail("关联的排名应该在1至排行榜最后一名的后一位");
        }

        //判断是否已存在排行榜
        Double flag = redisService.zScore(STUDENT_KEY, id);
        if (null != flag) {
            Asserts.fail("该学员已在名人堂排行榜中");
        }


        //判断是否有冲突，并处理
        dealRankConflict(STUDENT_KEY, rank);

        //添加当前排名
        Boolean flag2 = redisService.zAdd(STUDENT_KEY, id, rank);
        if (!flag2) {
            Asserts.fail("添加排行榜失败！");
        }
    }

    /**
     * 添加导师的Id到redis排行榜
     *
     * @param id   导师的id
     * @param rank 导师的排名
     */
    @Override
    public void addTutorIdWithRedis(Long id, Double rank) {

        //判断是否超出排名范围
        Long count = redisService.zCount(TUTOR_KEY);
        if (rank > count + 1 || rank < 1) {
            Asserts.fail("关联的排名应该在1至排行榜最后一名的后一位");
        }


        //判断是否已存在排行榜
        Double flag = redisService.zScore(TUTOR_KEY, id);
        if (null != flag) {
            Asserts.fail("该导师已在名人堂排行榜中");
        }

        //判断是否有冲突，并处理
        dealRankConflict(TUTOR_KEY, rank);

        //添加当前排名
        Boolean flag2 = redisService.zAdd(TUTOR_KEY, id, rank);
        if (!flag2) {
            Asserts.fail("添加排行榜失败！");
        }
    }

    /**
     * 根据id删除排行榜中的某个学生
     *
     * @param id
     */
    @Override
    public void delStudentByIdWithRedis(Long id) {

        Long flag = redisService.zRemove(STUDENT_KEY, id);
        if (flag < 1) {
            Asserts.fail("该学生不在排行旁中");
        }

    }

    /**
     * 根据id删除排行榜中的某个导师
     *
     * @param id
     */
    @Override
    public void delTutorIdWithRedis(Long id) {
        Long flag = redisService.zRemove(TUTOR_KEY, id);
        if (flag < 1) {
            Asserts.fail("该导师不在排行旁中");
        }
    }


    private void dealRankConflict(String key, Double rank) {
        Double score = redisService.zScore(key, rank.intValue());
        if (null != score && score.equals(rank)) {
            //将当前排名及往后的排名往加一名
            Set<Object> ids = redisService.zRange(key, 0, (long) (redisService.zCount(key) - rank));
            Iterator<Object> iterator = ids.iterator();
            while (iterator.hasNext()) {
                Object next = iterator.next();
                //Double s = redisService.zScore(STUDENT_KEY, next);
                redisService.zSetScore(key, next, 1);
            }
        }
    }

}
